package capimClientP;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

import com.sun.xml.internal.ws.handler.ClientSOAPHandlerTube;

/**
 * NetWork Listenner class
 * @author danielm pessoafpc
 *
 */
public class ReceivePacks implements Runnable{
	private Thread runner;
	private int port,expectedPackage;
	private DatagramSocket clientSocket;
	private DatagramPacket receivedPacket;
	private byte[]	receiveData = new byte[1024];
	
	/**
	 * Default contructor
	 * @param port port to listen on
	 */
	public ReceivePacks(int port) {
		this.setPort(port);
		this.setExpectedPackage(1);
		try {
			clientSocket = new DatagramSocket(Cap_in.localPort);
		} catch (SocketException e) {
			e.printStackTrace();
		}
		if(runner == null){
			runner = new Thread(this);
			runner.start();
		}
	}

	
	/**
	 * Thread main
	 */
	@Override
	public void run() {
		receivedPacket = new DatagramPacket(receiveData,receiveData.length);
		while(true){
			try {
				clientSocket.receive(receivedPacket);
				// System.out.println("Messagem Recebida!");
				String rdata = new String(receivedPacket.getData());
				System.out.println("rdata: "+rdata);
				
				// If is an ACK pkt
				if(rdata.charAt(0) == '2'){
					System.out.println("Received an ack: "+rdata);
					Cap_in.sendToNetwork.analizeReceivedPacket(rdata);
				} else {
					// Send an ACK
					
					// Construct a string to receive package sequence number
					StringBuilder numPackRecv = new StringBuilder();
					for(int i=1; i< rdata.length() ; i++){
						if(rdata.charAt(i)==':') break;
						numPackRecv.append(rdata.charAt(i));
					} 
					String packageSequenceNumber = new String(numPackRecv.toString().trim());
					if((Integer.parseInt(packageSequenceNumber)) == this.getExpectedPackage()){
						Cap_in.sendToNetwork.sendAck("2"+this.getExpectedPackage());
						this.setExpectedPackage(this.getExpectedPackage()+1);
					} else Cap_in.sendToNetwork.sendAck("2"+this.getExpectedPackage());
					
					// if Header Change, need to be changed HERE
					int index = 0;
		        	for(int i=1; i< rdata.length() ; i++){
		        		if(rdata.charAt(i) == ':'){
		        			index=i+1;
		        			break;
		        		}
		        	}
		        	
		        	// Check if is a new conection response and set the new port
					if((rdata.charAt(index) == '6')&&(rdata.charAt(index) == '2')){
						char[] port = new char[4];
						rdata.getChars(index+2, index+4, port, 0);
						String tport = new String(port);
						System.out.println("New port to connect: "+tport);
						Cap_in.sendToNetwork.setServerPort(Integer.parseInt(tport));
						System.out.println("new port-> "+Cap_in.sendToNetwork.getServerPort());
					} else {
						char[] data = new char[rdata.length()-index];
						rdata.getChars(index, rdata.length(), data, 0);
						String recData = new String(data);
						Cap_in.client.packReceived(recData);
					}
				}
				
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public void setPort(int port) {
		this.port = port;
	}

	public int getPort() {
		return port;
	}
	public int getExpectedPackage() {
		return expectedPackage;
	}

	public void setExpectedPackage(int expectedPackage) {
		this.expectedPackage = expectedPackage;
	}
}
